<?php

namespace App\Services;

use App\Exceptions\ServiceException;
use App\User;
use App\Utils\MiniProgramUtil;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;


/**
 * Created by PhpStorm.
 * User: rain
 * Date: 2018/10/30
 * Time: 4:12 PM
 */
class UserService
{
    private $miniProgramUtil;

    public function __construct(MiniProgramUtil $miniProgramUtil)
    {
        $this->miniProgramUtil = $miniProgramUtil;
    }

    /**
     * 小程序code注册
     * @param $code
     * @return \App\User
     * @throws \App\Exceptions\ServiceException
     * @throws \Exception
     */
    public function codeRegister($code)
    {
        $authSession = $this->miniProgramUtil->authSession($code);
        Log::info('code-login', $authSession);
        if (!isset($authSession['openid'])){
            throw new ServiceException('code验证失败');
        }

        $user = User::where(['open_id' => $authSession['openid']])->first();
        $newRecord = false;
        if (empty($user)){
            $newRecord = true;
            $user = new User();
            $user->api_token = Uuid::uuid1();
            $user->invite_code = \Faker\Provider\Uuid::uuid();
            $user->avatar = User::DEFAULT_AVATAR;
        }
        $user->open_id = $authSession['openid'];
        $user->session_key = $authSession['session_key'];
        if (empty($user->union_id) && isset($authSession['unionid'])){
            $user->union_id = $authSession['unionid'];
        }

        DB::beginTransaction();
        try{
            if (!$user->save()){
                throw new ServiceException('用户保存失败');
            }

            DB::commit();

            return $newRecord == false ? $user : User::find($user->id);
        }catch(\Exception $e){
            DB::rollBack();
            Log::error($e->getMessage());
            throw $e;
        }

    }


    /**
     * 小程序授权用户信息注册
     * @param $code
     * @param $encryptedData
     * @param $iv
     * @return \App\User|bool
     * @throws \Exception
     */
    public function wxRegister($code, $encryptedData, $iv)
    {
        try{
            $user = $this->codeRegister($code);

            $sessionKey = $user->session_key;
            $userInfo = $this->miniProgramUtil->decryptData($sessionKey, $iv, $encryptedData);
            if (empty($user->union_id) && isset($userInfo['unionId'])){
                $user->union_id = $userInfo['unionId'];
            }

            $user->nick_name = $userInfo['nickName'];
            $user->avatar = $userInfo['avatarUrl'];
            $user->sex = $userInfo['gender'];
            $user->language = $userInfo['language'];
            $user->city = $userInfo['city'];
            $user->province = $userInfo['province'];
            $user->country = $userInfo['country'];

            if (empty($user->avatar)){
                $user->avatar = User::DEFAULT_AVATAR;
            }
            if (!$user->save()){
                throw new ServiceException('用户保存失败');
            }

            return $user;
        }catch(\Exception $e){
            Log::error($e->getMessage());

            return $user;
            throw $e;
        }

    }


    /**
     * 解密微信信息
     * @param \App\User $user
     * @param $encryptedData
     * @param $iv
     * @return \App\User
     * @throws \Exception
     */
    public function wxAuth(User $user, $encryptedData, $iv)
    {
        try{
            $sessionKey = $user->session_key;
            $userInfo = $this->miniProgramUtil->decryptData($sessionKey, $iv, $encryptedData);
            if (empty($user->union_id) && isset($userInfo['unionId'])){
                $user->union_id = $userInfo['unionId'];
            }

            $user->nick_name = $userInfo['nickName'];
            $user->avatar = $userInfo['avatarUrl'];
            if (empty($user->avatar)){
                $user->avatar = User::DEFAULT_AVATAR;
            }
            if (!$user->save()){
                throw new ServiceException('用户保存失败');
            }

            return $user;
        }catch(\Exception $e){
            Log::error('头像解密失败' . $e->getMessage());
            throw $e;
        }

    }

    /**
     * 解密微信信息
     * @param \App\User $user
     * @param $code
     * @return \App\User
     * @throws \Exception
     */
    public function mobile(User $user, $code, $authType = 0, $authTargetId = 0)
    {
        if (!empty($user->mobile)){
            return $user;
        }

        try{
            $mobile = $this->miniProgramUtil->mobileByCode($code);

            $user->mobile = $mobile['phone_info']['purePhoneNumber'];
            $user->country_code = $mobile['phone_info']['countryCode'];
            if ($user->auth_target_id == 0 && $authTargetId > 0){
                $user->auth_type = $authType;
                $user->auth_target_id = $authTargetId;
            }

            $user->mobile_time = time();


            if (!$user->save()){
                throw new ServiceException('用户手机失败');
            }

            return $user;
        }catch(\Exception $e){
            Log::error('手机解密失败' . $e->getMessage());
            throw $e;
        }

    }


}
